﻿using System;
using System.Collections.Generic;
using System.IO;

namespace Teal.Compiler {

    /// <summary>
    /// 表示一个可动态扩展的字符串数组。
    /// </summary>
    public sealed class ByteArrayList {

        const int byteCount = 64;

        sealed class ByteArrayLinkNode {
            public byte[] data;
            public ByteArrayLinkNode next;

            public ByteArrayLinkNode(ByteArrayLinkNode next) {
                data = new byte[byteCount];
                this.next = next;
            }
        }

        int _currentIndex;

        ByteArrayLinkNode _lastData = new ByteArrayLinkNode(null);

        public int length {
            get {
                int sum = _currentIndex;

                for (ByteArrayLinkNode data = _lastData; data != _lastData; data = data.next) {
                    sum += byteCount;
                }

                return sum;
            }
        }

        public byte this[int index] {
            get {
                var lastData = _lastData;

                for (int i = index % byteCount; i >= 0; i--) {
                    lastData = lastData.next;
                }

                if (index >= _currentIndex) {
                    return 0;
                }

                return lastData.data[index];

            }
            set {
                var lastData = _lastData;

                for (int i = index % byteCount; i >= 0; i--) {
                    lastData = lastData.next;
                }

                if (index >= _currentIndex) {
                    return;
                }

                lastData.data[index] = value;

            }
        }

        public void add(byte value) {

            if (_currentIndex == byteCount - 1) {
                _currentIndex = 0;
                _lastData = _lastData.next = new ByteArrayLinkNode(_lastData.next);
            }

            _lastData.data[_currentIndex++] = value;

        }

        public void write(Stream target) {

            for (ByteArrayLinkNode data = _lastData; data != _lastData; data = data.next) {
                target.Write(data.data, 0, byteCount);
            }

            target.Write(_lastData.data, 0, _currentIndex);
        }

    }




}